语法
元素对象.addEventListener("事件类型",执行的函数)
监听三要素
实例
<button>按钮<button>
<script>
const btn = document.querySelector(".btn")
btn.addEventListener("click",function(){
alert("点击了")
})
</script>
案例
<body>
<h2>随机点名</h2>
<div class="box">
<span>名字是:</span>
<div class="qs">这里显示姓名</div>
</div>
<div class="btns">
<button class="start">开始</button>
<button class="end">结束</button>
</div>
<script>
// 数据数组
const arr = ['马超', '黄忠', '赵云', '关羽', '张飞']
// 获取元素
const start = document.querySelector(".start")
const end = document.querySelector(".end")
const content = document.querySelector(".qs")
// 设置单机事件
let timerId = 0
let random
start.addEventListener("click",function(){
timerId = setInterval(function(){
random = parseInt(Math.random()*arr.length)
content.innerText = arr[random]
},50)
})
end.addEventListener("click",function(){
clearInterval(timerId)
arr.splice(random,1)
if(arr.length == 1){
start.disabled = end.disabled = true
}
})
</script>
</body>
事件监听版本
元素.onclick = function(){
}
元素.addEventListener("click",function(){
})
区别
on方式会被覆盖,addEventListener方式可以绑定多次,拥有事件更多特性
鼠标事件
<body>
<div></div>
<script>
const div = document.querySelector("div")
// 鼠标悬浮
div.addEventListener("mouseenter",function(){
console.log("鼠标放在了div上面")
})
// 鼠标离开
div.addEventListener("mouseleave",function(){
console.log("鼠标离开")
})
</script>
</body>
焦点事件
键盘事件
<body>
<input type="text" name="" id="">
<script>
const input = document.querySelector("input")
input.addEventListener("keydown",function(){
console.log("键盘按下")
})
input.addEventListener("keyup",function(){
console.log("键盘弹起")
})
// 用户输入文本事件
input.addEventListener("input",function(){
console.log(input.value)
})
</script>
</body>
文本事件
案例:完整轮播图
```html
<div class="slider">
<div class="slider-wrapper">
<img src="../images/slider01.jpg" alt="" />
</div>
<div class="slider-footer">
<p>对人类来说会不会太超前了?</p>
<ul class="slider-indicator">
<li class="active"></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div class="toggle">
<button class="prev"><</button>
<button class="next">></button>
</div>
</div>
</div>
<script>
// 1. 初始数据
const data = [{
url: '../images/slider01.jpg',
title: '对人类来说会不会太超前了?',
color: 'rgb(100, 67, 68)'
},
{
url: '../images/slider02.jpg',
title: '开启剑与雪的黑暗传说!',
color: 'rgb(43, 35, 26)'
},
{
url: '../images/slider03.jpg',
title: '真正的jo厨出现了!',
color: 'rgb(36, 31, 33)'
},
{
url: '../images/slider04.jpg',
title: '李玉刚:让世界通过B站看到东方大国文化',
color: 'rgb(139, 98, 66)'
},
{
url: '../images/slider05.jpg',
title: '快来分享你的寒假日常吧~',
color: 'rgb(67, 90, 92)'
},
{
url: '../images/slider06.jpg',
title: '哔哩哔哩小年YEAH',
color: 'rgb(166, 131, 143)'
},
{
url: '../images/slider07.jpg',
title: '一站式解决你的电脑配置问题!!!',
color: 'rgb(53, 29, 25)'
},
{
url: '../images/slider08.jpg',
title: '谁不想和小猫咪贴贴呢!',
color: 'rgb(99, 72, 114)'
},
]
// 设置右按钮事件
const next = document.querySelector(".toggle .next")
const img = document.querySelector(".slider-wrapper img")
const p = document.querySelector(".slider-footer p")
const div = document.querySelector(".slider-footer")
// 抽取公共部分拿来复用
function render(){
img.src = data[i].url
p.innerText = data[i].title
div.style.backgroundColor = data[i].color
// 取消圆点样式
document.querySelector(".active").classList.remove("active")
// 添加圆点样式
document.querySelector(`ul li:nth-child(${i + 1})`).classList.add("active")
}
let i = 0
next.addEventListener("click", function () {
i++
if (i >= data.length) {
i = 0
}
render()
})
// 设置左按钮事件
const prev = document.querySelector(".toggle .prev")
prev.addEventListener("click",function(){
i--
if(i <= 0){
i = data.length - 1
}
render()
})
// 轮播定时
let timerId = setInterval(function(){
next.click()
},1000)
// 鼠标悬浮时暂停定时,离开时开启定时
const box = document.querySelector(".slider")
box.addEventListener("mouseenter",function(){
clearInterval(timerId)
})
box.addEventListener("mouseleave",function(){
timerId = setInterval(function(){
next.click()
},1000)
})
</script>
</body>
- 案例

```html
<body>
<div class="mi">
<input type="search" placeholder="小米笔记本">
<ul class="result-list">
<li><a href="#">全部商品</a></li>
<li><a href="#">小米11</a></li>
<li><a href="#">小米10S</a></li>
<li><a href="#">小米笔记本</a></li>
<li><a href="#">小米手机</a></li>
<li><a href="#">黑鲨4</a></li>
<li><a href="#">空调</a></li>
</ul>
</div>
<script>
const input = document.querySelector("[type='search']")
const ul = document.querySelector(".result-list")
input.addEventListener("focus",function(){
ul.style.display = "block"
input.classList.add("search")
})
input.addEventListener("blur",function(){
ul.style.display = "none"
input.classList.remove("search")
})
</script>
</body>
语法
元素.addEventListener("click",function(e){
})
<body>
<input type="text" name="" id="">
<script>
const input = document.querySelector("input")
input.addEventListener("keyup",function(e){
if(e.key == "Enter"){
console.log("按下了回车键")
}
})
</script>
</body>
部分常用属性
案例
<body>
<div class="wrapper">
<i class="avatar"></i>
<textarea id="tx" placeholder="发一条友善的评论" rows="2" maxlength="200"></textarea>
<button>发布</button>
</div>
<div class="wrapper">
<span class="total">0/200字</span>
</div>
<div class="list">
<div class="item" style="display: none;">
<i class="avatar"></i>
<div class="info">
<p class="name">清风徐来</p>
<p class="text">大家都辛苦啦,感谢各位大大的努力,能圆满完成真是太好了[笑哭][支持]</p>
<p class="time">2022-10-10 20:29:21</p>
</div>
</div>
</div>
<script>
const text = document.querySelector("#tx")
const total = document.querySelector(".total")
text.addEventListener("focus", function () {
total.style.opacity = "1"
})
text.addEventListener("blur", function () {
total.style.opacity = "0"
})
text.addEventListener("input", function () {
total.innerText = `${text.value.length}/200字`
})
const item = document.querySelector(".item")
const content = document.querySelector(".text")
const bt = document.querySelector("button")
bt.addEventListener("click", function () {
if (text.value.trim()) {
item.style.display = "block"
content.innerText = text.value
}
text.value = ""
total.innerText = '0/200字'
})
text.addEventListener("keyup", function (e) {
if (e.key == "Enter") {
bt.click()
}
})
</script>
</body>
概述
作用
补充:伪类选择器
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.ck:checked{
width: 30px;
height: 30px;
}
</style>
</head>
<body>
<input type="checkbox" name="" id="" class="ck">
<input type="checkbox" name="" id="" class="ck">
<input type="checkbox" name="" id="" class="ck">
</body>
<body>
<div class="tab">
<div class="tab-nav">
<h3>每日特价</h3>
<ul>
<li><a class="active" href="javascript:;">精选</a></li>
<li><a href="javascript:;">美食</a></li>
<li><a href="javascript:;">百货</a></li>
<li><a href="javascript:;">个护</a></li>
<li><a href="javascript:;">预告</a></li>
</ul>
</div>
<div class="tab-content">
<div class="item active"><img src="./images/tab00.png" alt="" /></div>
<div class="item"><img src="./images/tab01.png" alt="" /></div>
<div class="item"><img src="./images/tab02.png" alt="" /></div>
<div class="item"><img src="./images/tab03.png" alt="" /></div>
<div class="item"><img src="./images/tab04.png" alt="" /></div>
</div>
</div>
<script>
const as = document.querySelectorAll(".tab-nav li a")
for(let i = 0; i<as.length;i++){
as[i].addEventListener("mouseenter",function(){
// 清楚active类名
document.querySelector(".tab-nav .active").classList.remove("active")
// 添加active类名在当前鼠标悬浮的标签
this.classList.add("active")
// 清楚 div块内的active类名
document.querySelector(".tab-content .active").classList.remove("active")
// 添加
document.querySelector(`.tab-content div:nth-child(${i + 1})`).classList.add("active")
})
}
</script>
</body>
<body>
<table>
<tr>
<th class="allCheck">
<input type="checkbox" name="" id="checkAll"> <span class="all">全选</span>
</th>
<th>商品</th>
<th>商家</th>
<th>价格</th>
</tr>
<tr>
<td>
<input type="checkbox" name="check" class="ck">
</td>
<td>小米手机</td>
<td>小米</td>
<td>¥1999</td>
</tr>
<tr>
<td>
<input type="checkbox" name="check" class="ck">
</td>
<td>小米净水器</td>
<td>小米</td>
<td>¥4999</td>
</tr>
<tr>
<td>
<input type="checkbox" name="check" class="ck">
</td>
<td>小米电视</td>
<td>小米</td>
<td>¥5999</td>
</tr>
</table>
<script>
// 全选按钮
const allCheck = document.querySelector("#checkAll")
const checks = document.querySelectorAll(".ck")
allCheck.addEventListener("click", function () {
for (let i = 0; i < checks.length; i++) {
checks[i].checked = allCheck.checked
}
})
for(let i = 0; i < checks.length; i++){
checks[i].addEventListener("click",function(){
allCheck.checked = document.querySelectorAll(".ck:checked").length == checks.length
})
}
</script>
</body>
事件流和两个阶段说明
事件捕获
DOM.addEventListener(事件类型,事件处理函数,是否使用捕获机制)
事件冒泡
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
const fa = document.querySelector(".father")
const son = document.querySelector(".son")
document.addEventListener("click",function(){
alert("爷爷")
})
fa.addEventListener("click",function(){
alert("父")
})
son.addEventListener("click",function(e){
alert("儿")
})
</script>
</body>
阻止冒泡
son.addEventListener("click",function(e){
alert("儿")
// 组织流动传播【组织冒泡继续向上】
e.stopPropagation()
})
e.preventDefault()
解绑事件
<body>
<button id="l0">L0点击</button>
<button id="l2">L2点击</button>
<script>
const bt = document.querySelector("#l0")
// L0 版本
bt.onclick = function(){
alert("点击了")
// 接触绑定
bt.onclick = null
}
const btn = document.querySelector("#l2")
function butt(){
alert("点击了")
}
btn.addEventListener("click",butt)
// 解除绑定
btn.removeEventListener("click",butt)
</script>
</body>
匿名函数无法被解绑
原理
实现
<body>
<ul>
<li>我是第1个li</li>
<li>我是第2个li</li>
<li>我是第3个li</li>
<li>我是第4个li</li>
<p>我不需要添加</p>
</ul>
<script>
// 点击每个li 为当前li字体变为红色(通过冒泡来形成事件委托)
const ul = document.querySelector("ul")
ul.addEventListener("click",function(e){
// e.target 点击的当前标签对象
// 排除p标签 e.target.tagName 为点击当前的标签名
if(e.target.tagName == "LI"){
e.target.style.color = "red"
}
})
</script>
</body>
<body>
<div class="tab">
<div class="tab-nav">
<h3>每日特价</h3>
<ul>
<li><a class="active" href="javascript:;" data-id="0">精选</a></li>
<li><a href="javascript:;" data-id="1">美食</a></li>
<li><a href="javascript:;" data-id="2">百货</a></li>
<li><a href="javascript:;" data-id="3">个护</a></li>
<li><a href="javascript:;" data-id="4">预告</a></li>
</ul>
</div>
<div class="tab-content">
<div class="item active"><img src="./images/tab00.png" alt="" /></div>
<div class="item"><img src="./images/tab01.png" alt="" /></div>
<div class="item"><img src="./images/tab02.png" alt="" /></div>
<div class="item"><img src="./images/tab03.png" alt="" /></div>
<div class="item"><img src="./images/tab04.png" alt="" /></div>
</div>
</div>
<script>
const ul = document.querySelector(".tab-nav ul")
const divs = document.querySelectorAll(".tab-content div")
ul.addEventListener("click",function(e){
// 清楚 active类名
if(e.target.tagName == "A"){
document.querySelector(".tab-nav .active").classList.remove("active")
// 添加当前点击li的类型active
e.target.classList.add("active")
// 大盒子点击切换
// 清楚类名
document.querySelector(".tab-content .active").classList.remove("active")
divs[Number(e.target.dataset.id)].classList.add("active")
}
})
</script>
</body>
页面加载事件:load
监听页面所有资源加载完毕
window.addEventListener("load",function(){
})
不光可以监听整个页面资源加载完毕,也可以针对某个资源绑定load事件
页面加载事件:DOMContentLoaded
监听页面DOM加载完毕
document.addEventListener("DOMContentLoaded",function(){
})
元素滚动事件:scroll
很多网页需要检测用户吧页面滚动到某个区域做一些处理
window.addEventListener("scroll",function(){
})
监听某个元素的内部滚动直接给某个元素加即可
<style>
body {
height:3000px
}
div {
width: 200px;
height: 200px;
overflow:scroll;
display: none;
margin-top:200px
}
</style>
<body>
<div>
我有很多很多文字我有很多很多文字我有很多很多文字
我有很多很多文字我有很多很多文字我有很多很多文字
我有很多很多文字我有很多很多文字我有很多很多文字
我有很多很多文字我有很多很多文字我有很多很多文字
我有很多很多文字我有很多很多文字我有很多很多文字
我有很多很多文字我有很多很多文字我有很多很多文字
我有很多很多文字我有很多很多文字我有很多很多文字
我有很多很多文字我有很多很多文字我有很多很多文字
</div>
<script>
const div = document.querySelector("div")
div.addEventListener("scroll",function(){
// scrollTop被卷去的头部
console.log(div.scrollTop)
})
window.addEventListener("scroll",function(){
// 想知道页面滚动了多少像素,scrollTop
// 获取html元素写法:document.documentElement
const n = document.documentElement.scrollTop
if(n >= 100){
div.style.display = "block"
}else{
div.style.display = "none"
}
})
</script>
</body>
document.documentElement 返回对象为HTML元素
页面滚动事件——滚到到指定坐标
// 让页面滚动到 y 轴1000像素的位置
window.scrollTo(0,1000)
页面尺寸事件:resize
window.addEventListener("resize",function(){
})
window.addEventListener("resize",function(){
let w = document.documentElement.clientWidth
console.log(w)
})
页面尺寸事件——获取元素宽高
使用场景
尺寸:获取宽高
尺寸:获取位置
案例:仿京东固定导航栏
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.content {
overflow: hidden;
width: 1000px;
height: 3000px;
background-color: pink;
margin: 0 auto;
}
.backtop {
display: none;
width: 50px;
left: 50%;
margin: 0 0 0 505px;
position: fixed;
bottom: 60px;
z-index: 100;
}
.backtop a {
height: 50px;
width: 50px;
background: url(./images/bg2.png) 0 -600px no-repeat;
opacity: 0.35;
overflow: hidden;
display: block;
text-indent: -999em;
cursor: pointer;
}
.header {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 80px;
background-color: purple;
text-align: center;
color: #fff;
line-height: 80px;
font-size: 30px;
transition: all .3s;
}
.sk {
width: 300px;
height: 300px;
background-color: skyblue;
margin-top: 500px;
}
</style>
</head>
<body>
<div class="header">我是顶部导航栏</div>
<div class="content">
<div class="sk">秒杀模块</div>
</div>
<div class="backtop">
<img src="./images/close2.png" alt="">
<a href="javascript:;"></a>
</div>
<script>
const header = document.querySelector(".header")
const sk = document.querySelector(".sk")
// 页面滚动事件
window.addEventListener("scroll",function(){
// 获取页面卷去的头部
let n = document.documentElement.scrollTop
// 当前页面滚动到秒杀模块的时候,改变头部top的值
// 页面被卷去的头部 >= 秒杀模块的位置(offsetTop)
header.style.top = n >= sk.offsetTop ? 0 : "-80px"
})
</script>
</body>
<script>
// 页面滚动显示电梯导航栏
(function () {
const elevator = document.querySelector(".xtx-elevator")
const entry = document.querySelector(".xtx_entry")
window.addEventListener("scroll", function () {
let n = document.documentElement.scrollTop
// 判断超过entry的offsetTop则显示电梯导航栏
elevator.style.opacity = n >= entry.offsetTop ? 1 : 0
})
// 点击电梯导航栏顶部来将滚动条设置相应效果
const backTop = document.querySelector("#backTop")
backTop.addEventListener("click", function () {
// 将网页滚动条设置0即可
document.documentElement.scrollTo(0, 0)
})
})()
// 电梯导航栏每个点击效果
(function () {
const ul = document.querySelector(".xtx-elevator-list")
ul.addEventListener("click", function (e) {
// 设置类名效果 active
if (e.target.targetName = "A" && e.target.dataset.name) {
// 清楚类名 如果不存在,则DOM操作返回的元素为null
const a = document.querySelector(".xtx-elevator-list .active")
if (a) {
a.classList.remove("active")
}
// 添加类名
e.target.classList.add("active")
}
// 观察每个li标签内的a标签存在自定义属性,与要将滚动条到达的大盒子类名有所关联
// 将滚动条设置到大盒子卷去的offsetTop即可
const box = document.querySelector(`.xtx_goods_${e.target.dataset.name}`)
document.documentElement.scrollTop = box.offsetTop
})
// 大盒子找小盒子
window.addEventListener("scroll", function () {
// 清楚active
const a = document.querySelector(".xtx-elevator-list .active")
if (a) {
a.classList.remove("active")
}
const news = document.querySelector(".xtx_goods_new")
const popular = document.querySelector(".xtx_goods_popular")
const brand = document.querySelector(".xtx_goods_brand")
const category = document.querySelector(".xtx_goods_category")
const topic = document.querySelector(".xtx_goods_topic")
const n = document.documentElement.scrollTop
if (n >= news.offsetTop && n <= popular.offsetTop) {
document.querySelector("[data-name=new]").classList.add("active")
}else if(n >= popular.offsetTop && n <= brand.offsetTop){
document.querySelector("[data-name=popular]").classList.add("active")
}else if(n >= brand.offsetTop && n <= category.offsetTop){
document.querySelector("[data-name=brand]").classList.add("active")
}else if(n >= category.offsetTop && n <= topic.offsetTop){
document.querySelector("[data-name=category]").classList.add("active")
}else if(n >= topic.offsetTop){
document.querySelector("[data-name=topic]").classList.add("active")
}
})
}())
</script>